package ldh.im.admin.controller;

import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import ldh.common.PageResult;
import ldh.common.json.IncludeField;
import ldh.common.json.JsonViewFactory;
import ldh.common.mvc.DateEditor;
import ldh.im.base.constant.ArticleStatus;
import ldh.im.base.constant.CategoryStatus;
import ldh.im.base.pojo.CmsCategory;
import ldh.im.base.pojo.Department;
import ldh.im.base.pojo.ImTenant;
import ldh.im.base.pojo.Tenant;
import ldh.im.base.pojo.where.CmsCategoryWhere;
import ldh.im.base.service.CmsCategoryService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

/**
* @author: ldh
* @date: 2021-07-04 17:02:35
*/
@Controller
@RequestMapping("cmsCategory")
public class CmsCategoryController extends BaseController {

	@Resource(name = "cmsCategoryService")
	private CmsCategoryService cmsCategoryService;
	
	/**
	 * 字符串转化成时间
	 */
	@InitBinder  
	protected void initBinder(HttpServletRequest request,  
	                              ServletRequestDataBinder binder) throws Exception {  
	    //对于需要转换为Date类型的属性，使用DateEditor进行处理  
	    binder.registerCustomEditor(Date.class, new DateEditor());  
	} 

	@RequiresPermissions("cmsCategory:save")
    @RequestMapping(method = RequestMethod.POST, value = "/save")
    public String save(@ModelAttribute CmsCategory cmsCategory) throws Exception {
    	Objects.requireNonNull(cmsCategory);
		cmsCategory.setUpdateTime(new Date());
		cmsCategory.setPath("");
    	if (cmsCategory.getId() == null) {
    		if (cmsCategory.getParentId() == null) cmsCategory.setParentId(0L);
    		cmsCategory.setCreateTime(new Date());
			cmsCategoryService.insert(cmsCategory);
    	} else {
			cmsCategoryService.updateNotNullById(cmsCategory);
    	}
		initCategoryPath(cmsCategory);
    	return "redirect:/cmsCategory/list";
    }

	@RequiresPermissions("cmsCategory:save")
    @RequestMapping(method = RequestMethod.POST, value = "/save/json")
    @ResponseBody
    public String saveJson(@ModelAttribute CmsCategoryWhere cmsCategory) throws Exception {
    	Objects.requireNonNull(cmsCategory);
    	if (cmsCategory.getId() == null) {
			cmsCategoryService.insert(cmsCategory);
		} else {
			cmsCategoryService.updateNotNullById(cmsCategory);
		}
        return JsonViewFactory.create()
				.toJson();
    }

	@RequiresPermissions("cmsCategory:edit")
	@RequestMapping(method = RequestMethod.GET, value = "/toEdit/{id}")
    public String toEdit(@PathVariable Long id, Model model) throws Exception {
		CmsCategory cmsCategory = cmsCategoryService.getById(id);

    	model.addAttribute("cmsCategory", cmsCategory);
		model.addAttribute("active", "cmsCategory");
		model.addAttribute("tenants", getAllTenants());
		model.addAttribute("statusValues", CategoryStatus.values());
        return "cmsCategory/cmsCategoryEdit";
    }

	@RequiresPermissions("cmsCategory:toAdd")
	@RequestMapping(method = RequestMethod.GET, value = "/toAdd")
    public String toAdd(Model model) throws Exception {
		model.addAttribute("tenants", getAllTenants());
		model.addAttribute("active", "cmsCategory");
		model.addAttribute("statusValues", CategoryStatus.values());
        return "cmsCategory/cmsCategoryEdit";
    }

	@RequiresPermissions("cmsCategory:view")
	@RequestMapping(method = RequestMethod.GET, value = "/view/{id}")
    public String view(@PathVariable Long id, Model model) throws Exception {
		Objects.requireNonNull(id);
    	CmsCategory cmsCategory = cmsCategoryService.getById(id);
		cmsCategory.setTenant(tenantService.getById(cmsCategory.getTenantId()));
		if (cmsCategory.getParentId() != null && !cmsCategory.getParentId().equals(0L)) {
			cmsCategory.setParent(cmsCategoryService.getById(cmsCategory.getParentId()));
		}

    	model.addAttribute("cmsCategory", cmsCategory);
		model.addAttribute("active", "cmsCategory");
        return "cmsCategory/cmsCategoryView";
    }

	@RequiresPermissions("cmsCategory:edit")
	@ResponseBody
    @RequestMapping(method = RequestMethod.GET, value = "/view/json/{id}")
    public String viewJson(@PathVariable Long id, Model model) throws Exception {
		Objects.requireNonNull(id);
    	CmsCategory cmsCategory = cmsCategoryService.getById(id);
    	return JsonViewFactory.create()
				.setDateFormat("yyyy-MM-dd hh:mm:ss")
				.put("data", cmsCategory)
				.toJson();
    }

	@RequiresPermissions("cmsCategory:list")
	@RequestMapping(method = RequestMethod.GET, value = "/list")
	public String list(@ModelAttribute CmsCategoryWhere cmsCategoryWhere, Model model) {
		cmsCategoryWhere.setOrder("id desc");
		PageResult<CmsCategory> cmsCategorys = cmsCategoryService.findByCmsCategoryWhere(cmsCategoryWhere);
		cmsCategorys.getBeans().forEach(a-> {
			a.setTenant(tenantService.getById(a.getTenantId()));
			if(a.getParentId() != null && !a.getParentId().equals(0L)) {
				a.setParent(cmsCategoryService.getById(a.getParentId()));
			}
		});

		model.addAttribute("tenants", getAllTenants());
		model.addAttribute("cmsCategorys", cmsCategorys);
		model.addAttribute("active", "cmsCategory");
		model.addAttribute("cmsCategory", cmsCategoryWhere);
		model.addAttribute("statusValues", CategoryStatus.values());
		return "cmsCategory/cmsCategoryList";
	}

	@RequiresPermissions("cmsCategory:list")
	@RequestMapping(method = RequestMethod.GET, value = "/list2")
	public String list2(@ModelAttribute CmsCategoryWhere cmsCategoryWhere, Model model) {
		cmsCategoryWhere.setOrder("id desc");
		List<CmsCategory> cmsCategorys = cmsCategoryService.getAll(cmsCategoryWhere);

		Map<Long, ImTenant> tenantMap = new HashMap<>();
		cmsCategorys.forEach(d->{
			if (tenantMap.containsKey(d.getTenantId())) {
				d.setTenant(tenantMap.get(d.getTenantId()));
			} else {
				d.setTenant(tenantService.getById(d.getTenantId()));
				tenantMap.put(d.getTenantId(), d.getTenant());
			}
		});
		String json = JsonViewFactory.create().setExclusionStrategy(new IncludeField(CmsCategory.class,"id", "name", "description", "parentId", "status"))
				.toJson(cmsCategorys);

		model.addAttribute("tenants", getAllTenants());
		model.addAttribute("cmsCategorys", cmsCategorys);
		model.addAttribute("active", "cmsCategory");
		model.addAttribute("cmsCategory", cmsCategoryWhere);
		model.addAttribute("statusValues", CategoryStatus.values());
		model.addAttribute("treeJson", json);
		return "cmsCategory/cmsCategoryList2";
	}

	@RequestMapping(method = RequestMethod.GET, value = "/list/json2")
	@ResponseBody
	public String listJson2(Model model, HttpSession httpSession) {
		List<CmsCategory> managerModuleList = cmsCategoryService.getAll(new CmsCategoryWhere());
		List<CmsCategory> result = buildTree(managerModuleList);
		return JsonViewFactory.create().setExclusionStrategy(new IncludeField("id", "name", "description", "open", "children"))
				.toJson(result);
	}

	@RequiresPermissions("cmsCategory:edit")
	@RequestMapping(method = RequestMethod.GET, value = "/list/json")
	@ResponseBody
	public String listJson(@ModelAttribute CmsCategoryWhere cmsCategoryWhere, Model model) {
		cmsCategoryWhere.setOrder("id desc");
		PageResult<CmsCategory> cmsCategorys = cmsCategoryService.findByCmsCategoryWhere(cmsCategoryWhere);
		return JsonViewFactory.create()
				.setDateFormat("yyyy-MM-dd hh:mm:ss")
				.put("data", cmsCategorys)
				.toJson();
	}
	
	@RequiresPermissions("cmsCategory:delete")
	@RequestMapping(method = RequestMethod.GET, value = "/deleteById/json/{id}")
	@ResponseBody
	public String deleteJsonById(@PathVariable("id")Long id) {
		CmsCategory cmsCategory = cmsCategoryService.getById(id);
        Objects.requireNonNull(cmsCategory);
		cmsCategoryService.deleteById(id);
        return JsonViewFactory.create()
				.toJson();
    }

	private void initCategoryPath(CmsCategory cmsCategory) {
		Long parentId = cmsCategory.getParentId();
		if (parentId == null || parentId.equals(0L)) {
			cmsCategory.setPath(cmsCategory.getId()+"_");
		} else {
			CmsCategory parent = cmsCategoryService.getById(cmsCategory.getParentId());
			cmsCategory.setPath(parent.getPath() + cmsCategory.getId() + "_");
		}
		cmsCategoryService.updateNotNullById(cmsCategory);
	}

	private List<CmsCategory> buildTree(List<CmsCategory> categoryList) {
		List<CmsCategory> resultList = new ArrayList();
		Map<Long, CmsCategory> moduleMap = categoryList.stream().collect(Collectors.toMap(CmsCategory::getId, module -> module));
		for(CmsCategory category : categoryList) {
			category.setName(category.getName());
			if (category.getParentId() == null || category.getParentId().equals(0L)) {
				category.setOpen(true);
				resultList.add(category);
				continue;
			}
			CmsCategory parent = moduleMap.get(category.getParentId());
			if (parent == null) {
				parent.setOpen(true);
				resultList.add(category);
				continue;
			}
			if (parent.getChildren() == null) parent.setChildren(new ArrayList<>());
			parent.getChildren().add(category);
		}
		return resultList;
	}
}